package com.grace.cms.general.taglib;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import com.grace.redis.utils.RedisCache;
import com.grace.cms.common.domain.entity.CmsCategory;
import com.grace.cms.common.enums.CategoryNodeTypeEnums;
import com.grace.cms.general.cache.GeneralCategoryCacheService;
import com.grace.cms.general.utils.tree.CategoryTreeUtils;
import com.grace.cms.query.model.param.CategorySearchParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 分类标签
 */
@Service("categoryTag")
public class CategoryTag {

    @Autowired
    private GeneralCategoryCacheService categoryCacheService;
    @Autowired
    private RedisCache redisCache;

    /**
     * 获取分类
     * 
     * @param categoryId
     * @return
     */
    public CmsCategory selectCmsCategoryById(Long categoryId, String themeName) {
        return categoryCacheService.selectCmsCategoryById(categoryId, themeName);
    }

    /**
     * 
     * @param nodeType  类型
     * @param themeName 主题名字
     * @return
     */
    public List<CmsCategory> listCmsCategory(CategoryNodeTypeEnums nodeType,
            String themeName) {
        return this.listCategoryBy(null, nodeType, null, themeName);
    }

    /**
     * 
     * @param orderNum
     * @param nodeType
     * @param categoryId
     * @param themeName
     * @return
     */
    public List<CmsCategory> listCmsCategory(Long orderNum, CategoryNodeTypeEnums nodeType, Long categoryId,
            String themeName) {
        return this.listCategoryBy(orderNum, nodeType, categoryId, themeName);
    }

    /**
     * 
     * @param orderNum  排序
     * @param nodeType  类型
     * @param themeName 主题名字
     * @return
     */
    public List<CmsCategory> listCmsCategoryByOrder(CategoryNodeTypeEnums nodeType,
            String themeName, Long orderNum) {
        return this.listCategoryBy(orderNum, nodeType, null, themeName);
    }

    /**
     * 儿子节点
     * 
     * @param categoryId
     * @param nodeType   节点类型
     * @param themeName  主题名字
     * @return
     */
    public List<CmsCategory> listCategoryByParentId(long parentId, CategoryNodeTypeEnums nodeType, String themeName) {
        return this.listCategoryBy(null, nodeType, parentId, themeName);
    }

    /**
     * 
     * @param nodeType   类型
     * @param categoryId 分类Id
     * @return
     */
    public List<CmsCategory> listCategoryByType(String themeName, CategoryNodeTypeEnums nodeType, Long categoryId) {
        return this.listCategoryBy(null, nodeType, categoryId, themeName);
    }

    /**
     * 
     * @param orderNum   排序
     * @param categoryId 分类Id
     * @param themeName  主题名字
     * @return
     */
    public List<CmsCategory> listCategoryByOrderNum(String themeName, Long orderNum, long categoryId) {
        return this.listCategoryBy(orderNum, CategoryNodeTypeEnums.DEFAULT, categoryId, themeName);
    }

    /**
     * 获取分类树
     * 通过排序
     * 
     * @param orderNum
     * @param nodeType
     * @param categoryId
     * @param themeName
     * @return
     */
    public CmsCategory treeCmsCategoryByOrderNum(Long orderNum, CategoryNodeTypeEnums nodeType, Long categoryId,
            String themeName) {
        return CategoryTreeUtils.getCategoryTree(this.listCategoryBy(orderNum, nodeType, categoryId, themeName),
                categoryId == null ? 0L : categoryId);
    }

    /**
     * 获取分类树
     * 
     * @param orderNum
     * @param nodeType
     * @param categoryId
     * @param themeName
     * @return
     */
    public CmsCategory treeCmsCategory(CategoryNodeTypeEnums nodeType, Long categoryId,
            String themeName) {
        return CategoryTreeUtils.getCategoryTree(this.listCategoryBy(null, nodeType, categoryId, themeName),
                categoryId == null ? 0L : categoryId);
    }

    /**
     * 获取数量
     * 
     * @param themeName
     * @return
     */
    public int selectCategoryNum(String themeName, CategoryNodeTypeEnums nodeTypeEnums) {
        return categoryCacheService.selectCategoryNum(themeName, nodeTypeEnums);
    }

    /**
     * 检测分类是否支持
     * 
     * @param themeName
     * @param categoryId
     * @return
     */
    public boolean checkSupportCategory(String themeName, long categoryId) {
        return categoryCacheService.checkSupportCategory(themeName, categoryId);

    }

    /**
     * 
     * @param param
     * @return
     */
    public List<CmsCategory> listCmsCategory(CategorySearchParam param) {

        return categoryCacheService.listCmsCategory(param);
    }

    /**
     * 获取分类树
     * 
     * @param param
     * @return
     */
    public CmsCategory treeCategoryBySearchParam(CategorySearchParam param) {

        return categoryCacheService.treeCmsCategoryBySearchParam(param);
    }

    private List<CmsCategory> listCategoryBy(Long orderNum, CategoryNodeTypeEnums nodeType, Long categoryId,
            String themeName) {
        List<Long> categoryIds = categoryCacheService.listCategoryIds(orderNum, nodeType, categoryId, themeName);
        ArrayList<Object> categoryIdObjects = new ArrayList<>(categoryIds.stream()
                .map(Object::toString)
                .collect(Collectors.toList()));
        List<CmsCategory> categories = redisCache.getMultiCacheMapValue(
                GeneralCategoryCacheService.allKeyPrefix, categoryIdObjects);
        if (categories.stream().anyMatch(category -> category == null)) {
            return filterListNull(categoryIds, categories, orderNum, nodeType, categoryId, themeName);
        } else {
            return categories;
        }

    }

    private List<CmsCategory> filterListNull(List<Long> categoryIds, List<CmsCategory> categories, Long orderNum,
            CategoryNodeTypeEnums nodeType, Long categoryId,
            String themeName) {
        // 创建一个新的列表用于保存非空的 WebArticleVo 项
        List<CmsCategory> nonNullCategory = new ArrayList<>();
        for (int i = 0; i < categoryIds.size(); i++) {
            if (categories.get(i) != null) {
                nonNullCategory.add(categories.get(i));
            } else {
                CmsCategory category = this.selectCmsCategoryById(categoryIds.get(i), themeName);
                if (category != null) {
                    redisCache.setCacheMapValue(GeneralCategoryCacheService.allKeyPrefix,
                            Long.toString(category.getCategoryId()), category);
                    nonNullCategory.add(category);
                } else {

                }
            }
        }

        return nonNullCategory;
    }

}
